package com.geese.module.ceo.service;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

import com.geese.exception.BusinessException;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.geese.common.constants.BusinessConstants;
import com.geese.common.constants.Constants;
import com.geese.common.entity.Account;
import com.geese.common.entity.Building;
import com.geese.common.entity.Campus;
import com.geese.common.entity.Courier;
import com.geese.common.entity.School;
import com.geese.common.entity.User;
import com.geese.common.util.BeanUtil;
import com.geese.common.util.MD5Util;
import com.geese.common.util.PageUtil;
import com.geese.common.vo.Page;
import com.geese.common.vo.Paginator;
import com.geese.module.admin.vo.CeoQuery;
import com.geese.module.ceo.dao.BuildingMapper;
import com.geese.module.ceo.dao.CampusMapper;
import com.geese.module.ceo.dao.CourierMapper;
import com.geese.module.ceo.dao.SchoolMapper;
import com.geese.module.ceo.dto.WaiterDto;
import com.geese.module.ceo.vo.WaiterQuery;
import com.geese.module.user.dao.AccountMapper;
import com.geese.module.user.dao.UserMapper;
import com.github.pagehelper.PageHelper;
import com.google.common.base.Function;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;

/**
 * @author YeFangYi 
 */
@Service
public class CourierService {
	
	@Autowired
	private CourierMapper courierMapper;
	@Autowired
	private SchoolMapper schoolMapper;
	@Autowired
	private AccountMapper accountMapper;
	@Autowired
	private UserMapper userMapper;
	@Autowired
	private BuildingMapper buildingMapper;
	@Autowired
	private CampusMapper campusMapper;
	
	/**
	 * 根据userId查找小二
	 */
	public Courier findByUserId(Integer userId) {
		return courierMapper.findByUserId(userId);
	}
	
	/**
	 * 新增CEO
	 */
	public void saveCeo(Courier courier) {
		School school = schoolMapper.findById(courier.getSchoolId());
		if(school == null) {
			throw new BusinessException(120049);
		}
		Courier ceo = courierMapper.findBySchoolId(courier.getSchoolId(), BusinessConstants.CEO);
		if(ceo != null) {
			throw new BusinessException(120048);
		}
		Account mobileAccount = accountMapper.findByAccount(courier.getMobile());
		if(mobileAccount != null) {
			throw new BusinessException(120047);
		}
		
		User user = new User();
		user.setBlock(0);
		user.setEnable(1);
		user.setMobile(courier.getMobile());
		user.setUsername(courier.getName());
		user.setUserType(BusinessConstants.CEO_TYPE);
		userMapper.save(user);
		
		courier.setBlock(0);
		courier.setCeo(1);
		courier.setEnable(1);
		courier.setAudit(1);
		courier.setUserId(user.getId());
		courierMapper.save(courier);
		
		Account account = new Account();
		account.setAccount(courier.getMobile());
		account.setAllowPoint(0);
		account.setBlock(0);
		account.setEnable(1);
		account.setPassword(MD5Util.encrypt(BusinessConstants.DEFAULT_PWD));
		account.setUserId(user.getId());
		accountMapper.save(account);
	}

	/**
	 * 更新CEO
	 */
	public void updateCeo(Courier courier) {
		Courier model = courierMapper.findById(courier.getId());
		if(model == null || !Objects.equals(model.getCeo(), BusinessConstants.CEO)) {
			throw new BusinessException(120046);
		}
		User user = userMapper.findById(model.getUserId());
		user.setMobile(courier.getMobile());
		user.setUsername(courier.getName());
		userMapper.update(user);

		model.setName(courier.getName());
		model.setMobile(courier.getMobile());
		model.setCode(courier.getCode());
		courierMapper.update(model);
	}

	/**
	 * 删除CEO
	 */
	public void removeCeo(Integer id) {
		Courier courier = courierMapper.findById(id);
		if(courier == null || !Objects.equals(courier.getCeo(), BusinessConstants.CEO)) {
			throw new BusinessException(120045);
		}
		userMapper.remove(courier.getUserId());
		courierMapper.remove(id);
		accountMapper.removeByUserId(courier.getUserId());
	}

	/**
	 * 查询CEO列表
	 */
	public Map<String, Object> listCeoByQuery(CeoQuery query, Page page) {
		PageHelper.startPage(page.getCurrPage(), page.getPageSize(), " id DESC");
		List<Courier> courierList = courierMapper.listCeoByQuery(query);
		List<Map<String, Object>> ceoList = Lists.newArrayList();

		if (CollectionUtils.isNotEmpty(courierList)) {
			List<Integer> schoolIds = Lists.transform(courierList, new Function<Courier, Integer>() {
				@Override
				public Integer apply(Courier courier) {
					return courier.getSchoolId();
				}
			});
			List<School> schoolList = schoolMapper.listAllBySet(Sets.newHashSet(schoolIds));
			Map<Integer, School> schoolMap = Maps.uniqueIndex(schoolList, new Function<School, Integer>() {
				@Override
				public Integer apply(School school) {
					return school.getId();
				}
			});

			for (Courier courier : courierList) {
				Map<String, Object> temp = Maps.newHashMap();
				temp.put("id", courier.getId());
				temp.put("code", courier.getCode());
				temp.put("name", courier.getName());
				temp.put("mobile", courier.getMobile());
				temp.put("schoolId", courier.getSchoolId());
				temp.put("schoolName", schoolMap.get(courier.getSchoolId()).getName());
				ceoList.add(temp);
			}
		}
		Paginator<Courier> pageList = PageUtil.getPage(courierList);
		Map<String, Object> result = Maps.newHashMap();
		result.put(Constants.PAGE_INFO, pageList.getPageResult());
		result.put("ceoList", ceoList);

		return result;
	}

	/**
	 * 更新小二
	 */
	public void updateWaiter(Courier courier) {
		Courier model = courierMapper.findById(courier.getId());
		if(model == null || !Objects.equals(model.getCeo(), BusinessConstants.WAITER)) {
			throw new BusinessException(120040);
		}
		Campus campus = campusMapper.findById(courier.getCampusId());
		if(campus == null || !Objects.equals(model.getSchoolId(), campus.getSchoolId())) {
			throw new BusinessException(120039);
		}
		Building building = buildingMapper.findById(courier.getBuildingId());
		if(building == null || !Objects.equals(campus.getId(), building.getCampusId())) {
			throw new BusinessException(120038);
		}
		
		User user = userMapper.findById(model.getUserId());
		user.setMobile(courier.getMobile());
		user.setUsername(courier.getName());
		userMapper.update(user);

		model.setName(courier.getName());
		model.setMobile(courier.getMobile());
		model.setCode(courier.getCode());
		model.setCampusId(courier.getCampusId());
		model.setBuildingId(courier.getBuildingId());
		model.setStudentCard(courier.getStudentCard());
		courierMapper.update(model);
	}

	/**
	 * 删除小二
	 */
	public void remove(Integer id) {
		Courier waiter = courierMapper.findById(id);
		if(waiter == null || !Objects.equals(waiter.getCeo(), BusinessConstants.WAITER)) {
			throw new BusinessException(120040);
		}
		userMapper.remove(waiter.getUserId());
		courierMapper.remove(id);
		accountMapper.removeByUserId(waiter.getUserId());
	}
	
	/**
	 * 审核小二
	 */
	public void check(Integer id, Integer schoolId) {
		Courier waiter = courierMapper.findById(id);
		if(waiter == null || !Objects.equals(waiter.getCeo(), BusinessConstants.WAITER)) {
			throw new BusinessException(120040);
		}
		if(!Objects.equals(schoolId, waiter.getSchoolId())) {
			throw new BusinessException(120044);
		}
		courierMapper.check(waiter.getId());
	}

	/**
	 * 批量审核小二
	 */
	public void batchCheck(List<Integer> waiterIds, Integer schoolId) {
		List<Courier> waiterList = courierMapper.listByIds(waiterIds, BusinessConstants.WAITER);
		if (CollectionUtils.isEmpty(waiterList) || waiterList.size() != waiterIds.size()) {
			throw new BusinessException(120040);
		}
		for(Courier courier : waiterList) {
			if(!Objects.equals(schoolId, courier.getSchoolId())) {
				throw new BusinessException(120044);
			}
		}
		courierMapper.batchCheck(waiterIds);
	}

	/**
	 * 查询小二
	 */
	public Paginator<WaiterDto> listAllByQuery(WaiterQuery query, Page page) {
		PageHelper.startPage(page.getCurrPage(), page.getPageSize(), " id DESC");
		List<Courier> courierList = courierMapper.listWaiterByQuery(query);
		List<WaiterDto> result = Lists.newArrayList();
		if(CollectionUtils.isEmpty(courierList)) {
			return PageUtil.getPage(courierList, result);
		}
		List<School> schoolList = schoolMapper.listAllBySet(getSchoolSet(courierList));
		Map<Integer, School> schoolMap = Maps.uniqueIndex(schoolList, new Function<School, Integer>() {
			@Override
			public Integer apply(School school) {
				return school.getId();
			}
		});
		List<Campus> campusList = campusMapper.listAllBySet(getCampusSet(courierList));
		Map<Integer, Campus> campusMap = Maps.uniqueIndex(campusList, new Function<Campus, Integer>() {
			@Override
			public Integer apply(Campus campus) {
				return campus.getId();
			}
		});
		List<Building> buildingList = buildingMapper.listAllBySet(getBuildingSet(courierList));
		Map<Integer, Building> buildingMap = Maps.uniqueIndex(buildingList, new Function<Building, Integer>() {
			@Override
			public Integer apply(Building building) {
				return building.getId();
			}
		});
		
		for(Courier courier : courierList) {
			WaiterDto dto = BeanUtil.map(courier, WaiterDto.class);
			dto.setSchoolName(schoolMap.get(courier.getSchoolId()).getName());
			dto.setCampusName(campusMap.get(courier.getCampusId()).getName());
			dto.setBuildingName(buildingMap.get(courier.getBuildingId()).getName());
			result.add(dto);
		}
		
		return PageUtil.getPage(courierList, result);
	}
	
	private Set<Integer> getSchoolSet(List<Courier> courierList) {
		Set<Integer> resultSet = Sets.newHashSet();
		for(Courier courier : courierList) {
			resultSet.add(courier.getSchoolId());
		}
		return resultSet;
	}
	
	private Set<Integer> getCampusSet(List<Courier> courierList) {
		Set<Integer> resultSet = Sets.newHashSet();
		for(Courier courier : courierList) {
			resultSet.add(courier.getCampusId());
		}
		return resultSet;
	}
	
	private Set<Integer> getBuildingSet(List<Courier> courierList) {
		Set<Integer> resultSet = Sets.newHashSet();
		for(Courier courier : courierList) {
			resultSet.add(courier.getBuildingId());
		}
		return resultSet;
	}
}
